<template>
  <div class="fit row no-wrap justify-between items-start">
    <q-list class="q-col-125rem full-height bg-white-6 shadow-1 rounded-borders q-mr-md" separator>
      <q-item class="flex-center text-subtitle1 q-pt-md text-bold">
        {{ $t('ServiceList') }}
      </q-item>
      <MEmpty v-if="!serviceList.length"></MEmpty>
      <q-item v-for="service in serviceList" :key="service.id" v-ripple :active="service.id === currentService.id"
              active-class="service-active-cls" clickable @click="serviceClick(service)">
        <q-item-section avatar>
          <q-icon name="admin_panel_settings" size="1.25rem" />
        </q-item-section>
        <q-item-section>
          <qx-tooltip>{{ service[toI18nName('serviceNameZhCn')] }}</qx-tooltip>
        </q-item-section>
      </q-item>
    </q-list>
    <qx-tree v-model="selected" :filter-method="filterMethod" :loading="loading" :options="menuList" :props="props"
             classes="bg-white col" multiple strategy="strict" @change="treeChange">
      <template v-slot:tree-top>
        <div class="q-pl-xs q-gutter-sm q-mb-sm row items-end">
          <q-btn v-auth="['authMenu:save']" color="primary" icon="add" unelevated @click="handleCreate">
            {{ $t('Add') }}
          </q-btn>
          <q-btn v-auth="['authMenu:update']" :disable="isDisable" icon="mdi-square-edit-outline" outline
                 text-color="primary" @click="handleUpdate">
            {{ $t('Edit') }}
          </q-btn>
          <q-btn v-auth="['authMenu:delete']" :disable="isDisable" icon="delete" outline text-color="primary"
                 @click="handleDelete">
            {{ $t('Del') }}
          </q-btn>
          <q-badge class="q-pl-md q-pr-md" color="primary" outline>
            Tips:
            <q-icon class="q-pl-sm" name="storage" size="1rem"></q-icon>
            {{ $t('SystemCore.Directory') }}
            <q-icon class="q-pl-sm" name="insert_chart" size="1rem"></q-icon>
            {{ $t('SystemCore.Menu') }}
            <q-icon class="q-pl-sm" name="smart_button" size="1rem"></q-icon>
            {{ $t('SystemCore.Button') }}
          </q-badge>
        </div>
      </template>
      <template v-slot:header="{ prop }">
        <div class="row items-center">
          <q-icon :name="menuIcon(prop.node)" class="q-mr-sm" size="20px" />
          <div class="text-weight-bold">{{ prop.node.code }} -- {{ prop.node[toI18nName('menuNameZhCn')] }}</div>
        </div>
      </template>
      <template v-slot:body="{ prop }">
        <span>{{ prop.node.remark }}</span>
      </template>
    </qx-tree>
  </div>
  <q-modal v-model="modalVisible" :header="formInfo.id ? $t('Edit') : $t('Add')" :width="500" btnAlign="center"
           position="right" @confirm="submitForm">
    <qx-form ref="MenuForm" v-model="formInfo" :option="formOption">
      <template v-slot:menuIconAP>
        <q-icon :name="formInfo.menuIcon"></q-icon>
      </template>
    </qx-form>
  </q-modal>
</template>

<script setup>
import { i18n, toI18nName } from 'boot/i18n'
import { deleteAPI, postAPI, putAPI } from 'src/api'
import { createDialog, deepClone } from 'src/utils/utils'
import { userStores } from 'stores/user-stores'
import { computed, ref } from 'vue'

const userStore = userStores()
const menuList = ref([])
const selected = ref([])
const formInfo = ref({})
const MenuForm = ref(null)
const serviceList = ref([])
const parentMenus = ref([])
const selectedNode = ref({})
const currentService = ref(userStore.breadcrumbs || {})
const props = { label: toI18nName('menuNameZhCn'), children: 'childs' }
const isDisable = computed(() => !selected.value || selected.value.length !== 1)
const formOption = computed(() => {
  return {
    labelWidth: 100, searchLabelWidth: 70, selection: 'single', menuBtn: false, span: 22,
    column: [{
      label: `${i18n.t('SystemCore.SuperiorMenu')}`,
      field: 'parentId',
      type: 'tree',
      value: '-1',
      options: parentMenus.value,
      props,
      required: true
    }, {
      label: `${i18n.t('SystemCore.MenuCode')}`,
      field: 'code',
      required: true,
      inputClass: formInfo.value.menuType === 'B' ? '' : 'text-uppercase',
      readonly: formInfo.value.id && !import.meta.env.DEV
    }, {
      label: `${i18n.t('SystemCore.MenuNameENUS')}`,
      field: 'menuNameEnUs'
    }, {
      label: `${i18n.t('SystemCore.MenuName')}`,
      field: 'menuNameZhCn',
      required: true
    }, {
      label: `${i18n.t('SystemCore.MenuType')}`,
      field: 'menuType',
      type: 'radio',
      options: [{
        label: `${i18n.t('SystemCore.Directory')}`, value: 'F'
      }, {
        label: `${i18n.t('SystemCore.Menu')}`, value: 'M'
      }, {
        label: `${i18n.t('SystemCore.Button')}`, value: 'B'
      }],
      value: 'F',
      required: true
    }, {
      label: `${i18n.t('SystemCore.MenuICON')}`,
      field: 'menuIcon'
    }, {
      label: `${i18n.t('SystemCore.MenuPATH')}`,
      field: 'menuUrl',
      required: true
    }, {
      label: `${i18n.t('Sorting')}`,
      field: 'sortId',
      type: 'number',
      min: 0,
      decimals: 0,
      required: true
    }, {
      label: `${i18n.t('Remarks')}`,
      field: 'remark',
      type: 'textarea',
      maxlength: 200
    }]
  }
})

const loading = ref(false)
const modalVisible = ref(false)
const menuIcon = computed(() => {
  return menu => {
    if (menu.menuIcon) return menu.menuIcon
    if (menu.menuType === 'F') return 'storage'
    if (menu.menuType === 'M') return 'insert_chart'
    return 'smart_button'
  }
})

const getParentMenus = () => {
  const params = {
    orderByItems: [{ property: 'sortId', orderType: 'ASC' }],
    andDynamicQueryItems: [{
      property: 'serviceId', value: currentService.value.id, criterion: 'andEqualTo'
    }, {
      property: 'menuType', value: ['F', 'M'], criterion: 'andIn'
    }]
  }
  parentMenus.value = []
  postAPI('/auth/api/authMenu/listTree', params, data => {
    parentMenus.value = data
    parentMenus.value.unshift({ menuNameZhCn: '无', menuNameEnUs: 'Nothing', id: '-1' })
  })
}

const getServiceMenus = (isClearSelectedNode = true) => {
  if (!currentService.value || !currentService.value.id) {
    loading.value = false
    return
  }
  if (!loading.value) loading.value = true
  const params = {
    orderByItems: [{ property: 'sortId', orderType: 'ASC' }],
    andDynamicQueryItems: [{ property: 'serviceId', value: currentService.value.id, criterion: 'andEqualTo' }]
  }
  if (isClearSelectedNode) {
    selected.value = []
    selectedNode.value = {}
  }
  menuList.value = []
  postAPI('/auth/api/authMenu/listTree', params, data => {
    getParentMenus()
    menuList.value = data
    loading.value = false
  }, () => {
    loading.value = false
  })
}

const getServiceList = () => {
  loading.value = true
  postAPI('/auth/api/authService/list', { pageSize: '-1' }, data => {
    serviceList.value = data.rows
    getServiceMenus()
  }, () => {
    loading.value = false
  })
}
getServiceList()

const serviceClick = service => {
  if (service.id === currentService.value.id) return
  currentService.value = service
  getServiceMenus()
}

const treeChange = (target, node) => {
  if (target && target.length > 1) {
    selected.value = [target[1]]
    selectedNode.value = deepClone(node[1] || {})
    return
  }
  selectedNode.value = deepClone(node[0] || {})
}

const handleCreate = () => {
  const { childs = [], id = '-1', menuIcon, menuType, menuUrl = '/', parentId } = selectedNode.value || {}
  formInfo.value = { menuIcon, menuUrl, parentId: id, sortId: childs.length + 1 }
  if (menuType === 'F') formInfo.value.menuType = 'M'
  else if (menuType === 'M') formInfo.value.menuType = 'B'
  else if (menuType === 'B') {
    formInfo.value.menuType = 'B'
    formInfo.value.parentId = parentId
  } else formInfo.value.menuType = 'F'
  modalVisible.value = true
}

const handleUpdate = () => {
  formInfo.value = { ...selectedNode.value }
  modalVisible.value = true
}

const handleDelete = () => {
  createDialog({ msg: `${i18n.t('DelTips')}` }, () => {
    deleteAPI(`/auth/api/authMenu/${selected.value[0]}`, {}, () => getServiceMenus())
  }, () => {})
}

const submitForm = mDone => {
  MenuForm.value.validate((form, done) => {
    const API = form.id ? putAPI : postAPI
    form.serviceId = currentService.value.id
    if (['F', 'M'].includes(form.menuType) && form.code) form.code = form.code.toUpperCase()
    if (form.menuType === 'B') form.buttonPerms = form.code
    API('/auth/api/authMenu', form, () => {
      getServiceMenus(form.id === selectedNode.value.id)
      done()
      if (mDone) mDone()
    }, () => {
      done()
      if (mDone) mDone(false)
    })
  }, () => {
    if (mDone) mDone(false)
  })
}

const filterMethod = (node, filter) => {
  const query = (filter || '').toUpperCase()
  if ((node.code || '').toUpperCase().includes(query)) return true
  return (node[toI18nName('menuNameZhCn')] || '').toUpperCase().includes(query)
}
</script>